home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / graphic / hgrpic10.zip / A2B.C next >
C/C++ Source or Header  |  1991-05-02  |  9KB  |  336 lines

  1. /*
  2.  * A2B.C -- Program to convert Apple// Hi-Res Screen Dumps to
  3.  *          320x200x4 .PIC format IBM graphics files.  The result is an
  4.  *          IBM memory map (i.e., a BASIC BLOAD picture).
  5.  *
  6.  *          Program assumes that the input file is an uncompressed
  7.  *          280x192 color picture (Apple// HGR memory BSAVE) that
  8.  *          has already been ported to the IBM environment.
  9.  *
  10.  * Usage:   a2i <applefile> [WAIT]
  11.  *
  12.  *          If no extension is given, an extension of .RAW is assumed.
  13.  *          Output file generated uses same name as input file, with
  14.  *          a .PIC extension.
  15.  *
  16.  *          If you add "WAIT" to the command line (or anything really,
  17.  *          as all I check for is a 2nd parameter) the program will beep
  18.  *          and wait for a keypress before exiting.  Leaving this off the
  19.  *          command line makes the program work from a batch file for
  20.  *          multiple conversions.
  21.  */
  22.  
  23. /* INCLUDES */
  24.  
  25. #include <stdio.h>
  26. #include <process.h>
  27. #include <dir.h>
  28. #include <conio.h>
  29. #include <dos.h>
  30.  
  31. #include "cga.h"
  32.  
  33.  
  34.  
  35.  
  36. /* DEFINES */
  37.  
  38. #define ERROR -1
  39. #define A_OK   0
  40.  
  41. /*
  42.  * The following are the color equivalents in the CGA pallette that
  43.  * closely (relatively) approximate the Apple screen colors.  This
  44.  * program example thinks in the cyan/magenta/white pallette, but can
  45.  * easily be adapted to the green/red/yellow.
  46.  */
  47.  
  48. #define _A_BLACK   0
  49.  
  50. #define _A_VIOLET  _RED
  51. #define _A_GREEN   _BLUE
  52. #define _A_BLUE    _BLUE
  53. #define _A_ORANGE  _RED
  54. #define _A_WHITE   _WHITE
  55.  
  56.  
  57.  
  58.  
  59. /* GLOBALS */
  60.  
  61. UBYTE apple_memory[192][40];        /* Apple "memory" map */
  62.  
  63. int apple_lines[8][3] = {
  64.              {  0,  64, 128 },
  65.              {  8,  72, 136 },
  66.              { 16,  80, 144 },
  67.              { 24,  88, 152 },
  68.              { 32,  96, 160 },
  69.              { 40, 104, 168 },
  70.              { 48, 112, 176 },
  71.              { 56, 120, 184 }
  72.             };        /* Index table for Apple memory */
  73.  
  74. /*
  75.  * The Apple HGR screen is wonderfully convoluted (in several ways).  For
  76.  * instance, the color of a particular pixel on the Apple screen depends
  77.  * upon THREE (3) things:
  78.  *
  79.  *   1) Is the Apple screen byte an EVEN or ODD byte on the scanline?
  80.  *   2) Is the MSB of the screen byte SET?
  81.  *   3) Is the pixel/bit in question on an EVEN or ODD column?
  82.  *
  83.  * Pretty confusing, huh?  a2i_colors[][][] handles this as follows:
  84.  *
  85.  *   Pixel_color = a2i_colors[EVEN/ODD byte?][MSB SET?][EVEN/ODD column?]
  86.  */
  87.  
  88. int a2i_colors[2][2][2] = {
  89.                { /* EVEN byte        */
  90.                 { _A_VIOLET, _A_GREEN  },    /* MSB not set */
  91.                 { _A_BLUE  , _A_ORANGE }    /* MSB set     */
  92.                },
  93.                { /* ODD byte         */
  94.                 { _A_GREEN , _A_VIOLET },   /* MSB not set */
  95.                 { _A_ORANGE, _A_BLUE   }    /* MSB set     */
  96.                }
  97.               };
  98.  
  99.  
  100.  
  101.  
  102. /* FUNCTIONS */
  103.  
  104. /*
  105.  * load_apple_raw() -- Take a raw BSAVE file and load it into the temporary
  106.  *                     memory buffer.  This routine unscrambles Apple's
  107.  *                     memory mapping at the same time, so that the buffer
  108.  *                     becomes consecutive, as opposed to Apple's convoluted
  109.  *                     skipping from block to block.
  110.  */
  111. int load_apple_raw(const char *fname)
  112. {
  113.  int  i, vline, block, mline = 0;
  114.  FILE *fsave;
  115.  
  116.  
  117.  if((fsave = fopen(fname, "rb")) == NULL)
  118.   return ERROR;
  119.  
  120.  rewind(fsave);
  121.  
  122.  /*
  123.   * Even though we're dealing with Apple graphics, the screen map is still
  124.   * heavily tied to the text screen layout.  Apple's HGR screen is divided
  125.   * into 24 "blocks" of 8 lines per block (the main reason why when you do
  126.   * a BLOAD to the HGR screen, you get the infamous "venetian blind" load.
  127.   * Unfortunately, we end up stepping through memory (scanline-wise) as
  128.   * follows:
  129.   *
  130.   *   0, 64, 128, 8, 72, 136, ..., 184, 1, 65, 129, ...
  131.   *
  132.   * (i.e. line 0 is the first line of the file, line 1 is the 25th line of
  133.   * the file...wonderful, right?)
  134.   *
  135.   * If that isn't enough, every there are an additional 8 bytes of garbage
  136.   * space every 3 scanlines (reminiscent of IBM's CGA architecture).
  137.   *
  138.   * The easiest way I found to handle this is to create the apple_lines[][]
  139.   * table of base scanlines and index off of them.
  140.   */
  141.  
  142.  for(block=0;block<8;block++) 
  143.   for(mline=0;mline<24;mline++)
  144.    {
  145.    vline = apple_lines[mline / 3][mline % 3] + block;
  146.  
  147.    for(i=0;i<40;i++)
  148.     apple_memory[vline][i] = fgetc(fsave);
  149.  
  150.    if((mline % 3) == 2)
  151.     for(i=0;i<8;i++)
  152.      fgetc(fsave);
  153.    }
  154.  
  155.  fclose(fsave);
  156.  
  157.  return A_OK;
  158. }
  159.  
  160.  
  161.  
  162. /*
  163.  * apple_2_ibm() -- Take the "Apple map" image in the apple_memory[][]
  164.  *                  array and translate it into an CGA mode 4 image on
  165.  *                  the display.  xoff and yoff are pixel offsets on the
  166.  *                  CGA screen that result in the Apple image (280x192)
  167.  *                  being displayed dead center on the CGA screen (320x200).
  168.  */
  169. void apple_2_ibm(void)
  170. {
  171.  int   xoff = 20, yoff = 4;
  172.  int   i, j, k, which, line[280];
  173.  UBYTE abyte, abit;
  174.  
  175.  
  176.  for(i=0;i<192;i++)               /* 192 lines in an Apple HGR screen */
  177.   {
  178.  
  179.   /*
  180.    * The first thing we do is convert an Apple scanline to a CGA scanline,
  181.    * meaning that we must decode each Apple byte (7 pixels per byte) into
  182.    * CGA pixels.  line[] is the line buffer, each index holding one pixel's
  183.    * color value.
  184.    */
  185.  
  186.   for(j=0;j<40;j++)                    /* 280 pixels/line = 40 Apple bytes */
  187.    {
  188.    abyte = apple_memory[i][j];           /* Get an Apple byte                */
  189.  
  190.    which = (abyte & 0x80) == 0x80;     /* Which Apple color scheme?        */
  191.  
  192.    /*
  193.     * Now, cycle through the Apple byte one pixel at a time.  Since Apple
  194.     * bytes are encoded "backwards" to IBM screenlines, the least significant
  195.     * bit of the Apple byte is the far right pixel of the IBM byte.
  196.     * Therefore, the decompression process works as follows:
  197.     *
  198.     *   1) Grab LSB of Apple byte.
  199.     *   2) Set equivalent EGA pixel to correct Apple color (remember, Apple
  200.     *      colors depend upon:  A) whether the pixel is in an even or odd
  201.     *      column (on the Apple screen), and B) whether the high bit of the
  202.     *      Apple byte is set or not.
  203.     *   3) Shift Apple byte right one bit.
  204.     *   4) Repeat steps 1-3 for remaining 6 pixels in Apple byte
  205.     */
  206.  
  207.    for(k=0;k<7;k++)               /* 7 pixels per Apple byte          */
  208.     {
  209.     abit = abyte & 0x01;
  210.  
  211.     line[j*7 + k] = a2i_colors[j % 2][which][k % 2] * abit;
  212.  
  213.     abyte >>= 1;
  214.     }
  215.    }
  216.  
  217.   /*
  218.    * Now that we've built a CGA screen line, write it out to screen memory.
  219.    * The actual color displayed on the Apple screen depends not only on
  220.    * whether a given pixel is set or not, but also on whether adjacent
  221.    * pixels are set (if two adjacent pixels are on, the resulting color is
  222.    * WHITE, *not* the individual pixel colors).  The algorithm is:
  223.    *
  224.    *   IF (current pixel first on scanline)
  225.    *     Check the next pixel
  226.    *     IF (both pixels aren't black)
  227.    *       Write out a white pixel
  228.    *     ELSE
  229.    *       Write out the color of the first pixel
  230.    *   ELSE IF (current pixel last on scanline)
  231.    *     Check the previous pixel
  232.    *     IF (both pixels aren't black)
  233.    *       Write out white pixel
  234.    *     ELSE
  235.    *       Write out the color of the last pixel
  236.    *   ELSE
  237.    *     IF (current pixel not black) AND (previous OR next pixel not black)
  238.    *       Write out a white pixel
  239.    *     ELSE IF (current pixel black) AND (previous pixel same color as
  240.    *                                        next pixel)
  241.    *       Write out color of previous pixel
  242.    *     ELSE
  243.    *       Write out color of current pixel
  244.    *
  245.    * The convoluted part of the algorithm (the last part of the main IF
  246.    * structure) is because 2 ON pixels with 1 OFF pixel between them on
  247.    * the Apple screen are seen as a solid color (no gaps).
  248.    */
  249.  
  250.   for(k=0;k<280;k++)
  251.    {
  252.    if(k == 0)
  253.     {
  254.     if(line[k]!=_A_BLACK && line[k+1]!=_A_BLACK)
  255.      put_pixel(k + xoff, i + yoff, _A_WHITE);
  256.     else
  257.      put_pixel(k + xoff, i + yoff, line[k] );
  258.     }
  259.    else
  260.    if(k == 279)
  261.     {
  262.     if(line[k]!=_A_BLACK &